package com.softserveinc.moviedbapp.parser;

import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;

import com.softserveinc.moviedbapp.model.MovieInfo;
import com.softserveinc.moviedbapp.util.MovieAppConstants;

import org.xml.sax.Attributes;

import java.io.InputStream;
import java.util.ArrayList;

public class SAXParserMovieInfo implements IMovieDBMethodGetInfo {

	private static final String TAG = SAXParserMovieInfo.class.getSimpleName();

	/* names of the XML tags */
	static final String ID = "id";
	static final String OVERVIEW = "overview";
	static final String TRAILER = "trailer";
	static final String CAST = "cast";
	static final String PERSON = "person";
	static final String MOVIES = "movies";
	static final String MOVIE = "movie";
	static final String IMAGES = "images";
	static final String IMAGE = "image";

	private int retryCount = MovieAppConstants.RETRY_COUNT;

	private InputStream is;

	public SAXParserMovieInfo(final InputStream is) {
		this.is = is;
	}

	/* performs actual parsing */
	@Override
	public MovieInfo parseMovieInfo() {
		Log.d(TAG, "entered parseMovieInfo()");
		final MovieInfo currentMovieInfo = new MovieInfo();

		/* sets the root tag of the xml */
		RootElement rootTag = new RootElement("OpenSearchDescription");
		Element moviesTag = rootTag.getChild(MOVIES);
		Element movieTag = moviesTag.getChild(MOVIE);

		/* get the contents of the id tag */
		movieTag.getChild(ID).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovieInfo.setMovieId(Integer.parseInt(body));
			}
		});

		/* get the contents of the overview tag */
		movieTag.getChild(OVERVIEW).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovieInfo.setOverview(body);
			}
		});

		/* get the contents of the trailer tag */
		movieTag.getChild(TRAILER).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovieInfo.setTrailerUrl(body);
			}
		});

		/* get inside the images tag and get the contents of the image tag */
		Element imagesTag = movieTag.getChild(IMAGES);
		currentMovieInfo.setBackdropImagesUrls(new ArrayList<String>());

		imagesTag.getChild(IMAGE).setStartElementListener(new StartElementListener() {
			@Override
			public void start(final Attributes attributes) {

				/* choose the right image url (backdrop type and thumb size) */
				if ((attributes.getValue(0).equals("backdrop") && attributes.getValue(2).equals("thumb"))) {
					currentMovieInfo.getBackdropImagesUrlsList().add(attributes.getValue("url"));
				}
			}
		});

		/* get inside the images tag and get the contents of the image tag */
		Element castTag = movieTag.getChild(CAST);
		currentMovieInfo.setCast(new ArrayList<String>());

		castTag.getChild(PERSON).setStartElementListener(new StartElementListener() {
			@Override
			public void start(final Attributes attributes) {

				/* choose the actors from the cast */
				if (attributes.getValue(2).equals("Actor")) {
					currentMovieInfo.getCastList().add(attributes.getValue("name"));
				}
			}
		});

		/* for debug purposes only */
		movieTag.getChild("last_modified_at").setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				Log.d(TAG, "parser " + body + " </last_modified_at> ");
			}
		});

		/* for debug purposes only */
		rootTag.setEndElementListener(new EndElementListener() {

			@Override
			public void end() {
				Log.d(TAG, "parser </OpenSearchDescription> ");

			}
		});

		/* start parsing */
		/* try for 5 times to load image */
		while (retryCount > 0) {
			try {
				Log.d(TAG, "STARTED PARSING movie info with ANDROID SAX");
				Xml.parse(is, Xml.Encoding.UTF_8, rootTag.getContentHandler());
				Log.d(TAG, "\nSUCCESSFULLY COMPLETED PARSING movie info with ANDROID SAX");
				Log.d(TAG, currentMovieInfo.toString());
			} catch (Exception e) {
				retryCount--;
				Log.e(TAG, "Parsing failed MOVIE LIST. " + retryCount + " attemps left", e);
				continue;
			}
			break;
		}

		return currentMovieInfo;

	}
}
